/* Copyright (c) 2020-2024 Qualcomm Technologies International, Ltd. */
/* %%version */

#ifndef MCP_PRIVATE_H
#define MCP_PRIVATE_H

#include <stdlib.h>

#include "csr_bt_gatt_lib.h"

#include "mcp.h"
#include "service_handle.h"

#define McpMessageSend(TASK, MSG) CsrSchedMessagePut(TASK, MCP_PRIM, MSG)

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
#define CSR_BT_MCP_GET_SUPPLIER(_result)     ((CsrBtSupplier)((_result == GATT_OTSC_RESULT_CODE_SUCCESS) ? GATT_SUPPLIER_MCP_CLIENT : GATT_SUPPLIER_OTS_CLIENT))

#define OBJECT_READ_OFFSET      0x00
#define OBJECT_READ_LENGTH      0x00

typedef uint32                                       McpPendingOp;
#define MCP_PENDING_OP_NONE                          ((McpPendingOp) 0x00000000)
#define MCP_PENDING_OP_SELECT_OBJECT                 ((McpPendingOp) 0x00000001)
#define MCP_PENDING_OP_READ_OBJECT                   ((McpPendingOp) 0x00000002)
#define MCP_PENDING_OP_READ_OBJECT_METADATA          ((McpPendingOp) 0x00000004)
#define MCP_PENDING_OP_START_OBJECT_DISCOVERY        ((McpPendingOp) 0x00000008)
#define MCP_PENDING_OP_STOP_OBJECT_DISCOVERY         ((McpPendingOp) 0x000000010)

#endif/* EXCLUDE_GATT_OTS_CLIENT_MODULE */

/* Element of the list of MCS service handles */
struct McsSrvcHndl
{
    ServiceHandle srvcHndl;
#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
    ServiceHandle otsSrvcHndl;     /*! Service handle of the OTS client associated to this MCS instance*/
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */
    struct McsSrvcHndl *next;
};


typedef struct McsSrvcHndl McpMcsSrvcHndl;

typedef struct ProfileHandleListElement
{
    struct ProfileHandleListElement    *next;
    struct ProfileHandleListElement    *prev;
    ServiceHandle                   profile_handle;
} ProfileHandleListElm_t;

/* The Media Control Profile internal structure. */
typedef struct
{
    AppTaskData libTask;
    AppTask appTask;

    /*! ID of the connection */
    McpConnectionId cid;

    /*! Profile handle of the MCP instance*/
    McpProfileHandle mcpSrvcHndl;
    /*! Service handle of the MCS client associated to this MCP instance*/
    ServiceHandle mcsSrvcHndl;

    /*! MCS instance counter */
    uint16 mcsCounter;
    /*! MCS instance number */
    uint16 mcsNum;

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
    /*! Service handle of the OTS client associated to this MCP(GMCS)instance*/
    ServiceHandle otsSrvcHndl;
    /*! OTS instance counter */
    uint16 otsCounter;
    /*! OTS instance number */
    uint16 otsNum;

    McpObjectMetadataType  otsMetadataType;
    McpPendingOp           pendingOp;
    McpOptionalServices    optServices;
    McpOtsHandles          *otsData;
    uint8                  optServiceCount;
    uint8                  mcpReqCount;
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */
    /*! List of Service handle of the MCS instances discovered in the remote device */
    McpMcsSrvcHndl* firstMcsSrvcHndl;
    McpMcsSrvcHndl* lastMcsSrvcHndl;
} MCP;

typedef struct
{
    CsrCmnList_t profileHandleList;
} McpMainInst;

CsrBool mcpInstFindBySrvcHndl(CsrCmnListElm_t *elem, void *data);

CsrBool mcpProfileHndlFindByBtConnId(CsrCmnListElm_t *elem, void *data);

CsrBool mcpProfileHndlFindByMcsSrvcHndl(CsrCmnListElm_t *elem, void *data);

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
CsrBool mcpProfileHndlFindByOtsSrvcHndl(CsrCmnListElm_t *elem, void *data);
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */

McpMainInst *mcpGetMainInstance(void);

#define ADD_MCP_CLIENT_INST(_List) \
                         ServiceHandleNewInstance((void**)(&(_List)),sizeof(MCP))

#define FREE_MCP_CLIENT_INST(_Handle) \
                           ServiceHandleFreeInstanceData(_Handle)

#define MCP_ADD_SERVICE_HANDLE(_List) \
    (ProfileHandleListElm_t *)CsrCmnListElementAddLast(&(_List), \
                                              sizeof(ProfileHandleListElm_t))

#define MCP_REMOVE_SERVICE_HANDLE(_List,_ServiceHandle) \
                              CsrCmnListIterateAllowRemove(&(_List), \
                                        mcpInstFindBySrvcHndl,(void *)(&(_ServiceHandle)))

#define FIND_MCP_INST_BY_PROFILE_HANDLE(_Handle) \
                              (MCP *)ServiceHandleGetInstanceData(_Handle)

#define MCP_FIND_PROFILE_HANDLE_BY_BTCONNID(_List,_id) \
                              ((ProfileHandleListElm_t *)CsrCmnListSearch(&(_List), \
                                        mcpProfileHndlFindByBtConnId,(void *)(&(_id))))

#define MCP_FIND_PROFILE_HANDLE_BY_MCS_SERVICE_HANDLE(_List,_ServiceHandle) \
                              ((ProfileHandleListElm_t *)CsrCmnListSearch(&(_List), \
                                        mcpProfileHndlFindByMcsSrvcHndl,(void *)(&(_ServiceHandle))))

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
#define FIND_OTS_INST_BY_MCS_PROFILE_HANDLE(_List,_ServiceHandle) \
                     ((ProfileHandleListElm_t *)CsrCmnListSearch(&(_List), \
                                        otsHndleFindByMcsHndle,(void *)(&(_ServiceHandle))))

#define MCP_FIND_PROFILE_HANDLE_BY_OTS_SERVICE_HANDLE(_List,_ServiceHandle) \
                              ((ProfileHandleListElm_t *)CsrCmnListSearch(&(_List), \
                                        mcpProfileHndlFindByOtsSrvcHndl,(void *)(&(_ServiceHandle))))
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */

#endif /* MCP_PRIVATE_H */
